package com.opener.web.acl.interceptor;


import com.opener.web.acl.annotation.Auth;
import com.opener.web.acl.model.User;
import com.opener.web.acl.model.UserRole;
import com.opener.web.acl.service.AclService;
import com.opener.web.auth.constant.AuthConstants;
import com.opener.web.spring.exception.AclException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * Created by baboy on 02/12/2016.
 */
public class AclInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private AclService aclService;
    /**
     * This implementation always returns {@code true}.
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        HandlerMethod method = null;
        if (handler instanceof HandlerMethod){
            method = (HandlerMethod) handler;
        }
        if (method == null){
            throw new AclException("acl.error",request.getRequestURI());
        }
        Auth auth = method.getMethodAnnotation(Auth.class);
        //如果不要求验证
        if (auth != null && auth.acl() == false){
            return true;
        }
        //如果限定角色
        User user = (User)request.getAttribute(AuthConstants.SessionKey.USER);
        if (user == null){
            throw new AclException("acl.error",request.getRequestURI());
        }
        //判断是否拥有路由权限
        String route = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        List<UserRole> roles = aclService.getUserRoles(user.getUid());
        user.setRoles( roles);
        boolean isAuth = aclService.hasRouteRights(roles,route);
        if (!isAuth){
            throw new AclException("acl.error",request.getRequestURI());
        }
        return super.preHandle(request,response,handler) ;
    }
}
